<template>
  <!--  引入粒子特效-->
  <vue-particles
    class="bg-gray-500 h-screen w-screen fixed z-0"
    color="#fff"
    :particle-opacity="0.7"
    :particles-number="60"
    shape-type="circle"
    :particle-size="4"
    lines-color="#fff"
    :lines-width="1"
    :line-linked="true"
    :line-opacity="0.4"
    :lines-distance="150"
    :move-speed="2"
    :hover-effect="true"
    hover-mode="grab"
    :click-effect="true"
    click-mode="push"
  />
  <div class="page-container w-screen h-screen flex justify-center items-center">
    <div class="login-container">
      <div class="w-full flex justify-center items-center mb-8 text-white">Vue-Next-Element-Plus-Admin</div>
      <el-form ref="refLoginFrom" :model="loginFrom" :rules="loginFromRules">
        <el-form-item prop="username">
          <el-input
            v-model="loginFrom.username"
            type="text"
            :placeholder="t('login.usernameTip')"
            prefix-icon="el-icon-user-solid"
            class="login-input"
            autocomplete="on"
          />
        </el-form-item>
        <el-tooltip v-model="capsTooltip" :content="t('login.capsTip')" placement="right" manual>
          <el-form-item prop="password">
            <el-input
              v-model="loginFrom.password"
              :placeholder="t('login.passwordTip')"
              :type="passwordType"
              prefix-icon="el-icon-lock"
              class="login-input"
              autocomplete="on"
              @keyup="checkCapslock"
              @blur="capsTooltip = false"
              @keyup.enter.native="handleLogin"
            >
              <template #suffix>
                <span class="eye-icon" @click="changeEyes">
                  <svg-icon :icon-class="eyeState" />
                </span>
              </template>
            </el-input>
          </el-form-item>
        </el-tooltip>
        <el-form-item>
          <el-button
            class="login-btn"
            type="primary"
            :loading="loginLoading"
            :disabled="loginLoading"
            @click.native.prevent="handleLogin"
          >{{ t('login.login') }}</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>

</template>

<script>
import { reactive, ref, computed } from 'vue'
import { validUsername } from '@/utils/validate'
import { useStore } from 'vuex'
import { useRouter, useRoute } from 'vue-router'
import SvgIcon from '@/components/SvgIcon'
import { useI18n } from 'vue-i18n'
export default {
  name: 'Login',
  components: { SvgIcon },
  setup(props, ctx) {
    const store = useStore()
    const router = useRouter()
    const route = useRoute()
    const { t } = useI18n()
    const loginFrom = reactive({
      username: 'admin', password: 'password'
    })

    const validateUsername = (rule, value, callback) => {
      if (!validUsername(value)) {
        callback(new Error('请输入您的用户名'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (value.length < 6) {
        callback(new Error('密码不能小于6位'))
      } else {
        callback()
      }
    }
    const loginFromRules = reactive({
      username: [{ required: true, trigger: 'blur', validator: validateUsername }],
      password: [{ required: true, trigger: 'blur', validator: validatePassword }]
    })

    // 大写锁定提示
    const capsTooltip = ref(false)
    const checkCapslock = (e) => {
      const { key } = e
      capsTooltip.value = key && key.length === 1 && (key >= 'A' && key <= 'Z')
    }

    // 密码框
    const passwordType = ref('password')
    const isOpenEyes = computed(() => { return passwordType.value === 'password' })
    const eyeState = computed(() => { return isOpenEyes.value ? 'eyes_opened' : 'eyes_close' })
    const changeEyes = () => {
      if (isOpenEyes.value) {
        passwordType.value = 'text'
      } else {
        passwordType.value = 'password'
      }
    }

    const getOtherQuery = (query) => {
      return Object.keys(query).reduce((acc, cur) => {
        if (cur !== 'redirect') {
          acc[cur] = query[cur]
        }
        return acc
      }, {})
    }

    const redirect = computed(() => {
      const query = route.query
      if (query) {
        return query.redirect
      }
      return null
    })

    const otherQuery = computed(() => {
      const query = route.query
      if (query) {
        return getOtherQuery(query)
      }
      return {}
    })

    const refLoginFrom = ref(null)
    const loginLoading = ref(false)
    const handleLogin = () => {
      refLoginFrom.value.validate(async(valid) => {
        if (valid) {
          loginLoading.value = true
          const { code } = await store.dispatch('login', loginFrom)
          if (code === 20000) {
            await router.push({ path: redirect.value || '/', query: otherQuery.value })
          }
          loginLoading.value = false
        }
      })
    }

    return {
      loginFrom, passwordType, eyeState, capsTooltip, t,
      loginLoading, loginFromRules, refLoginFrom,
      checkCapslock, changeEyes, handleLogin
    }
  }
}
</script>

<style lang="scss" scoped>
.page-container{
  .login-container{
    z-index: 1;
    width: 500px;
    max-width: 80%;
    min-height: 300px;
    background-image: linear-gradient(120deg, rgba(161,196,253,0.6) 0%, rgba(194,233,251,0.6) 100%);
    @apply rounded-lg p-8;
    .login-input{
      @apply w-full;
      ::v-deep(input){
        background-color: transparent;
      }
      ::v-deep(.el-input__icon){
        color: #fff;
      }
      .eye-icon{
        @apply mr-2;
        color: #fff;
      }
    }
    .login-btn{
      @apply w-full;
    }
  }
}

</style>
